home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Internet Info 1994 March
/
Internet Info CD-ROM (Walnut Creek) (March 1994).iso
/
networking
/
ip
/
ka9q
/
src.arc
/
MAIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-08-19
|
11KB
|
577 lines
/* Main network program - provides both client and server functions */
#define HOSTNAMELEN 32 /* changed from 16 by Bdale 860812 */
#include <stdio.h>
#include <time.h>
#include <io.h>
#ifdef ANSIPROTO
#include <stdarg.h>
#endif
#include "global.h"
#include "mbuf.h"
#include "socket.h"
#include "iface.h"
#include "ftpcli.h"
#include "telnet.h"
#include "ax25tnc.h"
#include "remote.h"
#include "session.h"
#include "cmdparse.h"
#include "ax25.h"
#include "kiss.h"
#include "enet.h"
#include "timer.h"
#include "proc.h"
#include "tty.h"
#include "daemon.h"
#include "usock.h"
#include "netrom.h"
#include "ip.h"
#include "tcp.h"
#include "udp.h"
#include "pc.h"
#include "commands.h"
extern struct cmds Cmds[],Startcmds[],Stopcmds[];
extern int32 Heapsize;
extern struct daemon Daemons[];
extern char Version[];
extern char *Startup; /* File to read startup commands from */
extern int Refuse_echo;
extern int Unix_line_mode;
extern char *Rempass;
#ifndef MSDOS /* PC uses F-10 key always */
static char Escape = 0x1d; /* default escape character is ^] */
#endif
char Badhost[] = "Unknown host %s\n";
char Hostname[HOSTNAMELEN];
static char Prompt[] = "net> ";
char Nospace[] = "No space!!\n"; /* Generic malloc fail message */
struct mbuf *Hopper;
static FILE *Logfp;
static struct mbuf *Cmdq;
static struct proc *Cmdpp;
extern struct cmds Attab[];
int
main(argc,argv)
int argc;
char *argv[];
{
char *inbuf,*intmp;
FILE *fp;
struct daemon *tp;
struct mbuf *bp;
int c;
extern char *optarg;
extern int optind;
while((c = getopt(argc,argv,"s:d:m:")) != EOF){
switch(c){
case 's': /* Number of sockets */
Nusock = atoi(optarg);
break;
case 'd': /* Root directory for various files */
initroot(optarg);
break;
case 'm': /* Heap memory size */
Heapsize = 1024 * atol(optarg);
break;
}
}
kinit();
ioinit(Heapsize);
sockinit();
Cmdpp = mainproc("cmdintrp");
ttysetmode(TTY_ECHO|TTY_EDIT);
printf("KA9Q Internet Protocol Package, v%s\n",Version);
printf("Copyright 1989 by Phil Karn, KA9Q\n");
fflush(stdout);
Sessions = (struct session *)calloc(Nsessions,sizeof(struct session));
if(optind < argc){
/* Read startup file named on command line */
if((fp = fopen(argv[optind],READ_TEXT)) == NULLFILE)
printf("Can't read config file %s: %s\n",
argv[optind],sys_errlist[errno]);
} else {
fp = fopen(Startup,READ_TEXT);
}
if(fp != NULLFILE){
inbuf = malloc(BUFSIZ);
intmp = malloc(BUFSIZ);
while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
strcpy(intmp,inbuf);
if(cmdparse(Cmds,inbuf,NULL) != 0){
printf("input line: %s",intmp);
}
}
fclose(fp);
free(inbuf);
free(intmp);
}
/* Start background Daemons */
for(tp=Daemons;;tp++){
if(tp->name == NULLCHAR)
break;
newproc(tp->name,tp->stksize,tp->fp,0,NULLCHAR,NULL);
}
/* Now loop forever, processing commands */
for(;;){
printf(Prompt);
while(Cmdq == NULLBUF)
pwait(&Cmdq);
bp = dequeue(&Cmdq);
(void)cmdparse(Cmds,bp->data,Current);
free_p(bp);
ttysetmode(TTY_ECHO|TTY_EDIT);
}
}
/* Keyboard input process */
void
keyboard(i,v1,v2)
int i;
void *v1;
void *v2;
{
int c;
struct mbuf *bp;
/* Keyboard process loop */
for(;;){
c = kbread();
#ifndef MSDOS
if(c == Escape && Escape != 0)
c = -2;
#endif
/* c == -2 means the command escape key */
if(c == -2){
/* Save current tty mode and set cooked */
if(Current != NULLSESSION && Mode == CONV_MODE){
Current->ttymode = ttygetmode();
Mode = CMD_MODE;
ttysetmode(TTY_ECHO|TTY_EDIT);
printf("\n");
/* Wake up the command interpreter */
alert(Cmdpp,0);
}
/* Else give to line editor; if done, queue it */
} else if((bp = ttydriv(c)) != NULLBUF){
switch(Mode){
case CMD_MODE:
enqueue(&Cmdq,bp);
break;
case CONV_MODE:
enqueue(&Current->input,bp);
break;
}
}
}
}
/* Standard commands called from main */
int
dodelete(argc,argv,p)
int argc;
char *argv[];
void *p;
{
int i;
for(i=1;i < argc; i++){
if(unlink(argv[i]) == -1){
printf("Can't delete %s: %s\n",
argv[i],sys_errlist[errno]);
}
}
return 0;
}
int
dorename(argc,argv,p)
int argc;
char *argv[];
void *p;
{
if(rename(argv[1],argv[2]) == -1)
printf("Can't rename: %s\n",sys_errlist[errno]);
return 0;
}
int
doexit(argc,argv,p)
int argc;
char *argv[];
void *p;
{
reset_all();
iostop();
exit(0);
return 0; /* To satisfy lint */
}
int
dohostname(argc,argv,p)
int argc;
char *argv[];
void *p;
{
if(argc < 2)
printf("%s\n",Hostname);
else
strncpy(Hostname,argv[1],HOSTNAMELEN);
return 0;
}
int
dolog(argc,argv,p)
int argc;
char *argv[];
void *p;
{
static char logname[15];
if(argc < 2){
if(Logfp)
printf("Logging to %s\n",logname);
else
printf("Logging off\n");
return 0;
}
if(Logfp){
fclose(Logfp);
Logfp = NULLFILE;
}
if(strcmp(argv[1],"stop") != 0){
strncpy(logname,argv[1],15);
Logfp = fopen(logname,APPEND_TEXT);
}
return 0;
}
int
dohelp(argc,argv,p)
int argc;
char *argv[];
void *p;
{
register struct cmds *cmdp;
int i,j;
printf("Main commands:\n");
for(i=0,cmdp = Cmds;cmdp->name != NULL;cmdp++,i++){
printf("%s",cmdp->name);
if((i % 4) == 3)
printf("\n");
else {
for(j=strlen(cmdp->name);j < 16; j++)
putchar(' ');
}
}
if((i % 4) != 0)
printf("\n");
return 0;
}
int
doecho(argc,argv,p)
int argc;
char *argv[];
void *p;
{
if(argc < 2){
if(Refuse_echo)
printf("Refuse\n");
else
printf("Accept\n");
} else {
if(argv[1][0] == 'r')
Refuse_echo = 1;
else if(argv[1][0] == 'a')
Refuse_echo = 0;
else
return -1;
}
return 0;
}
/* set for unix end of line for remote echo mode telnet */
int
doeol(argc,argv,p)
int argc;
char *argv[];
void *p;
{
if(argc < 2){
if(Unix_line_mode)
printf("Unix\n");
else
printf("Standard\n");
} else {
if(strcmp(argv[1],"unix") == 0)
Unix_line_mode = 1;
else if(strcmp(argv[1],"standard") == 0)
Unix_line_mode = 0;
else {
return -1;
}
}
return 0;
}
/* Attach an interface
* Syntax: attach <hw type> <I/O address> <vector> <mode> <label> <bufsize> [<speed>]
*/
int
doattach(argc,argv,p)
int argc;
char *argv[];
void *p;
{
return subcmd(Attab,argc,argv,p);
}
/* Manipulate I/O device parameters */
int
doparam(argc,argv,p)
int argc;
char *argv[];
void *p;
{
register struct iface *ifp;
for(ifp=Ifaces;ifp != NULLIF;ifp = ifp->next){
if(strcmp(argv[1],ifp->name) == 0)
break;
}
if(ifp == NULLIF){
printf("Interface \"%s\" unknown\n",argv[1]);
return 1;
}
if(ifp->ioctl == NULLFP){
printf("Not supported\n");
return 1;
}
/* Pass rest of args to device-specific code */
return (*ifp->ioctl)(ifp,argc-2,argv+2);
}
/* Display or set IP interface control flags */
int
domode(argc,argv,p)
int argc;
char *argv[];
void *p;
{
register struct iface *ifp;
for(ifp=Ifaces;ifp != NULLIF;ifp = ifp->next){
if(strcmp(argv[1],ifp->name) == 0)
break;
}
if(ifp == NULLIF){
printf("Interface \"%s\" unknown\n",argv[1]);
return 1;
}
if(argc < 3){
printf("%s: %s\n",ifp->name,
(ifp->flags & CONNECT_MODE) ? "VC mode" : "Datagram mode");
return 0;
}
switch(argv[2][0]){
case 'v':
case 'c':
case 'V':
case 'C':
ifp->flags = CONNECT_MODE;
break;
case 'd':
case 'D':
ifp->flags = DATAGRAM_MODE;
break;
default:
printf("Usage: %s [vc | datagram]\n",argv[0]);
return 1;
}
return 0;
}
#ifndef MSDOS
static int
doescape(argc,argv,p)
int argc;
char *argv[];
void *p;
{
if(argc < 2)
printf("0x%x\n",Escape);
else
Escape = *argv[1];
return 0;
}
#endif MSDOS
/* Generate system command packet. Synopsis:
* remote [-p port#] [-k key] [-a hostname] <hostname> reset|exit|kickme
*/
int
doremote(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct sockaddr_in fsock;
int s,c;
char *data,x;
extern int errno;
extern char *optarg;
extern int optind;
int16 port,len;
char *key = NULLCHAR;
int klen;
int32 addr = 0;
char *cmd,*host;
port = IPPORT_REMOTE; /* Set default */
optind = 1; /* reinit getopt() */
while((c = getopt(argc,argv,"a:p:k:s:")) != EOF){
switch(c){
case 'a':
addr = resolve(optarg);
break;
case 'p':
port = atoi(optarg);
break;
case 'k':
key = optarg;
klen = strlen(key);
break;
case 's':
Rempass = strdup(optarg);
return 0; /* Only set local password */
}
}
if(optind > argc - 2){
printf("Insufficient args\n");
return -1;
}
host = argv[optind++];
cmd = argv[optind];
if((s = socket(AF_INET,SOCK_DGRAM,0)) == -1){
printf("socket failed\n");
return 1;
}
len = 1;
/* Did the user include a password or kickme target? */
if(addr != 0)
len += sizeof(int32);
if(key != NULLCHAR)
len += klen;
if(len == 1)
data = &x;
else
data = malloc(len);
fsock.sin_family = AF_INET;
fsock.sin_addr.s_addr = resolve(host);
fsock.sin_port = port;
switch(cmd[0]){
case 'r':
data[0] = SYS_RESET;
if(key != NULLCHAR)
strncpy(&data[1],key,klen);
break;
case 'e':
data[0] = SYS_EXIT;
if(key != NULLCHAR)
strncpy(&data[1],key,klen);
break;
case 'k':
data[0] = KICK_ME;
if(addr != 0)
put32(&data[1],addr);
break;
default:
printf("Unknown command %s\n",cmd);
goto cleanup;
}
/* Form the command packet and send it */
if(sendto(s,data,len,0,(char *)&fsock,sizeof(fsock)) == -1){
printf("sendto failed: %s\n",sys_errlist[errno]);
goto cleanup;
}
cleanup:
if(data != &x)
free(data);
close_s(s);
return 0;
}
/* Log messages of the form
* Tue Jan 31 00:00:00 1987 44.64.0.7:1003 open FTP
*/
#ifdef ANSIPROTO
void
log(int s,char *fmt, ...)
{
va_list ap;
char *cp;
long t;
int fd,i;
struct sockaddr fsocket;
if(Logfp == NULLFILE)
return;
time(&t);
cp = ctime(&t);
rip(cp);
i = SOCKSIZE;
fprintf(Logfp,"%s",cp);
if(getpeername(s,(char *)&fsocket,&i) != -1)
fprintf(Logfp," %s",psocket(&fsocket));
fprintf(Logfp," - ");
va_start(ap,fmt);
vfprintf(Logfp,fmt,ap);
va_end(ap);
fprintf(Logfp,"\n");
fflush(Logfp);
#ifdef MSDOS
/* MS-DOS doesn't really flush files until they're closed */
fd = fileno(Logfp);
if((fd = dup(fd)) != -1)
close(fd);
#endif
}
#else
/*VARARGS2*/
void
log(s,fmt,arg1,arg2,arg3,arg4,arg5)
int s;
char *fmt;
int arg1,arg2,arg3,arg4,arg5;
{
char *cp;
long t;
int fd,i;
struct sockaddr fsocket;
if(Logfp == NULLFILE)
return;
time(&t);
cp = ctime(&t);
rip(cp);
i = SOCKSIZE;
fprintf(Logfp,"%s",cp);
if(getpeername(s,(char *)&fsocket,&i) != -1)
fprintf(Logfp," %s",psocket(&fsocket));
fprintf(Logfp," - ");
fprintf(Logfp,fmt,arg1,arg2,arg3,arg4,arg5);
fprintf(Logfp,"\n");
fflush(Logfp);
#ifdef MSDOS
/* MS-DOS doesn't really flush files until they're closed */
fd = fileno(Logfp);
if((fd = dup(fd)) != -1)
close(fd);
#endif
}
#endif